package httpclient

import (
	"net"
	"net/http"
	"time"
)

// Config HTTP客户端配置
type Config struct {
	// 连接池配置
	MaxIdleConns        int           // 最大空闲连接数
	MaxIdleConnsPerHost int           // 每个主机的最大空闲连接数
	MaxConnsPerHost     int           // 每个主机的最大连接数
	IdleConnTimeout     time.Duration // 空闲连接超时时间

	// 超时配置
	Timeout               time.Duration // 请求总超时时间
	DialTimeout           time.Duration // 建立连接超时时间
	TLSHandshakeTimeout   time.Duration // TLS握手超时时间
	ResponseHeaderTimeout time.Duration // 响应头超时时间

	// 其他配置
	KeepAlive          time.Duration // Keep-Alive时间
	DisableKeepAlives  bool          // 是否禁用Keep-Alive
	DisableCompression bool          // 是否禁用压缩
}

// DefaultConfig 默认配置
func DefaultConfig() *Config {
	return &Config{
		MaxIdleConns:          1000,
		MaxIdleConnsPerHost:   100,
		MaxConnsPerHost:       100,
		IdleConnTimeout:       90 * time.Second,
		Timeout:               30 * time.Second,
		DialTimeout:           10 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ResponseHeaderTimeout: 10 * time.Second,
		KeepAlive:             30 * time.Second,
		DisableKeepAlives:     false,
		DisableCompression:    false,
	}
}

// NewHttpClient 创建默认配置的HTTP客户端
func NewHttpClient() *http.Client {
	return NewHttpClientWithConfig(DefaultConfig())
}

// NewHttpClientWithConfig 根据配置创建HTTP客户端
func NewHttpClientWithConfig(config *Config) *http.Client {
	transport := &http.Transport{
		MaxIdleConns:          config.MaxIdleConns,
		MaxIdleConnsPerHost:   config.MaxIdleConnsPerHost,
		MaxConnsPerHost:       config.MaxConnsPerHost,
		IdleConnTimeout:       config.IdleConnTimeout,
		TLSHandshakeTimeout:   config.TLSHandshakeTimeout,
		ResponseHeaderTimeout: config.ResponseHeaderTimeout,
		DisableKeepAlives:     config.DisableKeepAlives,
		DisableCompression:    config.DisableCompression,
	}

	// 配置Dialer
	if config.DialTimeout > 0 || config.KeepAlive > 0 {
		dialer := &net.Dialer{
			Timeout:   config.DialTimeout,
			KeepAlive: config.KeepAlive,
		}
		transport.DialContext = dialer.DialContext
	}

	return &http.Client{
		Transport: transport,
		Timeout:   config.Timeout,
	}
}

// ConfigOption 配置选项函数类型
type ConfigOption func(*Config)

// WithMaxIdleConns 设置最大空闲连接数
func WithMaxIdleConns(maxIdleConns int) ConfigOption {
	return func(c *Config) {
		c.MaxIdleConns = maxIdleConns
	}
}

// WithMaxIdleConnsPerHost 设置每个主机的最大空闲连接数
func WithMaxIdleConnsPerHost(maxIdleConnsPerHost int) ConfigOption {
	return func(c *Config) {
		c.MaxIdleConnsPerHost = maxIdleConnsPerHost
	}
}

// WithMaxConnsPerHost 设置每个主机的最大连接数
func WithMaxConnsPerHost(maxConnsPerHost int) ConfigOption {
	return func(c *Config) {
		c.MaxConnsPerHost = maxConnsPerHost
	}
}

// WithTimeout 设置请求总超时时间
func WithTimeout(timeout time.Duration) ConfigOption {
	return func(c *Config) {
		c.Timeout = timeout
	}
}

// WithDialTimeout 设置建立连接超时时间
func WithDialTimeout(dialTimeout time.Duration) ConfigOption {
	return func(c *Config) {
		c.DialTimeout = dialTimeout
	}
}

// WithTLSHandshakeTimeout 设置TLS握手超时时间
func WithTLSHandshakeTimeout(tlsTimeout time.Duration) ConfigOption {
	return func(c *Config) {
		c.TLSHandshakeTimeout = tlsTimeout
	}
}

// WithKeepAlive 设置Keep-Alive时间
func WithKeepAlive(keepAlive time.Duration) ConfigOption {
	return func(c *Config) {
		c.KeepAlive = keepAlive
	}
}

// WithDisableKeepAlives 设置是否禁用Keep-Alive
func WithDisableKeepAlives(disable bool) ConfigOption {
	return func(c *Config) {
		c.DisableKeepAlives = disable
	}
}

// NewHttpClientWithOptions 使用选项模式创建HTTP客户端
func NewHttpClientWithOptions(options ...ConfigOption) *http.Client {
	config := DefaultConfig()
	for _, option := range options {
		option(config)
	}
	return NewHttpClientWithConfig(config)
}
